/*
 * Copyright 2010 Christoph Widulle (christoph.widulle@googlemail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */



package com.android1.amarena2d.engine;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * If a SharedResource has no longer any refs, it will place itself here.
 * This will avoid leaks.
 */
public class ResourceManager extends EngineObject implements Resource.Consumer {

    private ArrayList<Resource> resources;
    private List<Resource> immutableResources;
    private ArrayList<Resource> toRemove;

    public ResourceManager() {
        this(100);
    }

    public ResourceManager(int size) {
        resize(size);
    }

    public void resize(int size) {
        resources = new ArrayList<Resource>(size);
        immutableResources = Collections.unmodifiableList(resources);
        toRemove = new ArrayList<Resource>(size);
    }

    /**
     * Marks a resource to be persistent. It will not ne disposed on Scene.exit().
     * To achieve this the ResourceManager holds a reference by himself.
     *
     * @param resource
     */
    public void markPersistent(Resource resource) {
        resource.obtainRef(this);
    }

    public void revokePersistent(Resource resource) {
        resource.releaseRef(this);
    }

    public boolean store(Resource resource) {
        if (!resources.contains(resource)) {
            resources.add(resource);
            return true;
        }
        return false;
    }

    public List<Resource> getResources() {
        return immutableResources;
    }

    public boolean remove(Resource resource) {
        return resources.remove(resource);
    }

    /**
     * Disposes and removes all SharedResources without a reference.
     */
    public void disposeAll() {
        toRemove.clear();
        for (int i = 0; i < resources.size(); i++) {
            Resource resource = resources.get(i);
            if (!resource.hasRefs()) {
                resource.dispose();
                toRemove.add(resource);
            }
        }
        resources.removeAll(toRemove);
    }

    /**
     * Disposes and removes all SharedResources even they have a reference.
     */
    public void forceDisposeAll() {

        for (int i = 0; i < resources.size(); i++) {
            Resource resource = resources.get(i);
            resource.releaseAllRefs();
            resource.dispose();
        }
        resources.clear();
    }
}

